<template>
  <div class="main-todo" draggable="true">
    <input
      v-model.trim="content"
      @keyup.enter="handelAdd"
      class="add-todo"
      type="text"
      placeholder="What to do? ↵"
      autofocus
    />
    <label
      :class="[
        'select-all',
        completedQuantity == todos.length ? '' : 'un-select-all',
      ]"
      @click="handleSelectAll(completedQuantity == todos.length)"
    ></label>
    <div class="content-list">
      <draggable v-model="filterTodos" v-bind="{ animation: 300 }">
        <transition-group>
          <todo-item
            v-for="todo in filterTodos"
            :key="todo.id"
            :todo="todo"
            @toggle="handleToggle"
            @edit="handleUpdate"
            @delete="handleDelete"
          ></todo-item>
        </transition-group>
      </draggable>
    </div>

    <todo-info
      :infoShow="todos.length != 0"
      :clearShow="completedQuantity != 0"
      :total="total"
      @toggle="handleState"
      @clear="handleClear"
    ></todo-info>
  </div>
</template>

<script>
//导入拖拽组件
import draggable from 'vuedraggable'

//导入子组件
import TodoInfo from './coms/TodoInfo.vue'
import TodoItem from './coms/TodoItem.vue'

export default {
  name: 'MainTodo',
  components: {
    TodoInfo,
    TodoItem,
    draggable,
  },
  data() {
    return {
      todos: JSON.parse(localStorage.getItem('vue-todo') || '[]'),
      filterTodos: [],
      content: '',
      state: 'all',
    }
  },
  computed: {
    total() {
      return this.todos.filter((item) => item.completed == 0).length
    },
    completedQuantity() {
      //完成项数量
      return this.todos.filter((item) => item.completed == 1).length
    },
    filterData() {
      // 比在 handleState 中修改 filterTodos 高效，但与draggable的v-model冲突，拖拽无效
      // switch (this.state) {
      //   case 'all':
      //     return this.todos
      //   case 'active':
      //     return this.todos.filter((item) => item.completed == 0)
      //   case 'completed':
      //     return this.todos.filter((item) => item.completed == 1)
      //   default:
      //     return this.todos
      // }
    },
  },
  created() {
    this.filterTodos = this.todos
  },
  watch: {
    todos: {
      deep: true, //开启深度侦听, 不管多少层, 只要数据变化, 都可以被侦听到
      handler(newTodos) {
        // console.log('修改')
        localStorage.setItem('vue-todo', JSON.stringify(newTodos))
        //根据当前查看的状态为filterTodos赋值，解决在已完成/未完成选项中修改状态后，列表不变化的问题
        this.handleState(this.state)
      },
    },
  },
  methods: {
    //在localStorage中存储为一个键（todos数组）还是多个键（todo对象）？
    //此处采用方案1，存储为对象数组
    handelAdd() {
      if (this.content == '') {
        alert('请输入待办内容')
        return
      }

      //id怎么存？ 方案1：Date.now()
      const obj = { id: Date.now(), content: this.content, completed: 0 }
      this.todos.push(obj)

      this.content = ''
      //3. 更新到localStorage（会在watch监听中实现）
    },
    handleToggle(id) {
      this.todos.forEach((item) => {
        // 1. 根据id查找需要修改的todo对象
        if (item.id == id) {
          // 2. 更新todo对象的content的值
          item.completed = item.completed ? 1 : 0
        }
      })
      //3. 更新到localStorage（会在watch监听中实现）
    },
    handleUpdate(id, content) {
      /*
      vue.$emit('edit', '参1', '参2')有多个参数时：
      方法1： 模板中插件引用处，方法不写参数括号；方法定义处的括号内写上对应个数的形参
      方法2： 模板中插件引用出，方法参数写作：arguments；方法定义处用一个形参接收，格式为数组，使用为 形参[0]
      */
      this.todos.forEach((item) => {
        // 1. 根据id查找需要修改的todo对象
        if (item.id == id) {
          // 2. 更新todo对象的content的值
          item.content = content
        }
      })
    },
    handleDelete(id) {
      // 发送ajax请求, 调用delete接口

      this.todos.forEach((item, index) => {
        // 1. 根据id查找需要删除的todo对象
        if (item.id == id) {
          // 2. 删除
          this.todos.splice(index, 1)
        }
      })
    },
    handleState(s) {
      this.state = s
      switch (s) {
        case 'all':
          this.filterTodos = this.todos
          break
        case 'active':
          this.filterTodos = this.todos.filter((item) => item.completed == 0)
          break
        case 'completed':
          this.filterTodos = this.todos.filter((item) => item.completed == 1)
          break
        default:
          this.filterTodos = this.todos
      }
    },
    handleClear() {
      // forEach中多次更新数组，而watch中只侦听到todos的一次改变，为何？
      // this.todos.forEach((item, index) => {
      //   // 1. 查找已完成的todo项
      //   if (item.completed == 1) {
      //     // 2. 删除。删除后索引变化，影响后续遍历
      //     this.todos.splice(index, 1)
      //   }
      // })

      //直接重新给this.todos赋值，比一项项删除更干脆！
      //且此法只被watch侦听到一次，从而只执行一次更新到localStorage的操作
      this.todos = this.todos.filter((item) => item.completed == 0)
    },
    handleSelectAll(selected) {
      // 获取最大索引
      const maxIndex = this.todos.length - 1
      // 当前是否全选状态（以确定将todos设置为全选 或 全不选）
      const completed = selected ? 0 : 1

      const temp = this.todos
      this.todos.forEach((item, index) => {
        //此处被watch监听了多少次？
        item.completed = completed
      })
    },
  },
}
</script>

<style lang="stylus">
@import '@/assets/styles/theme.styl';

.main-todo
  //css自定义属性，记录input与info的高度，服务于列表的自适应高度
  --other-height: 172px;
  position: relative;
  width: 60%;
  max-width: 900px;
  min-width: 600px;
  max-height: calc(100vh - var(--header-height) - var(--footer-height)); /* 100vh：浏览器高度 */
  margin: 0 auto;
  padding: 16px;
  background-color rgba(255,255,255,0.4);
  border-radius: 26px;
  box-shadow: 3px 3px 5px #aaa;

  .add-todo
    width: 100%;
    padding: 16px 16px 16px 60px;
    border: none;
    background-color: rgba(255,255,255,0.7);
    font-size: 24px;
    font-family: inherit; //防止font-weight失效
    color $cat
    outline: none;
    border-radius: 63px;
    box-sizing: border-box;
    // 区分placeholder和输入文本的样式
    &::placeholder
      font-weight: 100;
    &:focus
      box-shadow: 0 0 2px 2px $blue;

  // 列表的自适应高度与滚动条
  .content-list
    max-height: calc(100vh - var(--header-height) - var(--footer-height) - var(--other-height));
    overflow: auto;
    /* 滚动条的美化 */
    &::-webkit-scrollbar
      /*滚动条整体样式*/
      width : 10px;  /*高宽分别对应横竖滚动条的尺寸*/
      height: 1px;
    &::-webkit-scrollbar-thumb
      /*滚动条里面小方块*/
      border-radius: 10px;
      box-shadow   : inset 0 0 5px rgba(0, 0, 0, 0.1);
      background   : $cat2;
    &::-webkit-scrollbar-track
      /*滚动条里面轨道*/
      box-shadow   : inset 0 0 5px rgba(0, 0, 0, 0.1);
      border-radius: 10px;
      background   : #ededed;

  //全选与否
  label.select-all
    position: absolute;
    top: 37px;
    left: 33px;
    &::after
      content: url('@/assets/images/全选.svg');
    &.un-select-all::after
      content: url('@/assets/images/未全选.svg');
</style>
